package com.tentative.competition.schedule.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tentative.competition.common.core.result.PageResult;
import com.tentative.competition.common.enums.BannerStatusEnum;
import com.tentative.competition.common.enums.BannerTypeEnum;
import com.tentative.competition.common.model.schedule.param.BannerInfoAddParam;
import com.tentative.competition.common.model.schedule.param.BannerStatusEditParam;
import com.tentative.competition.common.model.schedule.resp.AwardResp;
import com.tentative.competition.common.model.schedule.resp.BannerInfoResp;
import com.tentative.competition.common.model.schedule.resp.BannerResp;
import com.tentative.competition.common.model.schedule.vo.FileVo;
import com.tentative.competition.common.utils.DataConversionUtils;
import com.tentative.competition.schedule.domain.ScheduleBannerInfo;
import com.tentative.competition.schedule.mapper.ScheduleBannerInfoMapper;
import com.tentative.competition.schedule.service.ScheduleBannerInfoService;
import com.tentative.competition.schedule.service.ScheduleFileInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SmileH
 * @since 2023-06-22
 */
@Service
public class ScheduleBannerInfoServiceImpl extends ServiceImpl<ScheduleBannerInfoMapper, ScheduleBannerInfo> implements IService<ScheduleBannerInfo> , ScheduleBannerInfoService {

    @Lazy
    @Autowired
    private ScheduleFileInfoService fileInfoService;

    @Autowired
    private DataConversionUtils dataConversionUtils;

    @Override
    public PageResult<BannerInfoResp> pageList(BannerInfoAddParam param) {
        IPage<BannerInfoResp> infoResps = baseMapper.pageList(param,new Page<>(param.getPageNum(),param.getPageSize()));
        if (CollUtil.isEmpty(infoResps.getRecords())){
            return new PageResult<>();
        }
        //组装附件信息
        Set<Long> fileIds = CollUtil.newHashSet();
        Set<String> fileList = infoResps.getRecords().stream().map(BannerInfoResp::getBannerImg).collect(Collectors.toSet());
        fileList.forEach(x->{
            List<String> list = dataConversionUtils.strToList(x);
            list.forEach(j->fileIds.add(Long.parseLong(j)));
        });
        if (CollUtil.isNotEmpty(fileIds)){
            Map<Long, FileVo> voMap = fileInfoService.selectFileMapByIds(fileIds);
            infoResps.getRecords().forEach(x->{
                List<FileVo> fileVos = new ArrayList<>();
                List<String> toList = dataConversionUtils.strToList(x.getBannerImg());
                toList.forEach(j->fileVos.add(voMap.get(Long.parseLong(j))));
                x.setBannerUrlVo(fileVos);
            });

        }
        PageResult<BannerInfoResp> pageResult = new PageResult<>();
        pageResult.setContent(infoResps.getRecords());
        pageResult.setTotal(infoResps.getTotal());
        return pageResult;
    }

    @Override
    public BannerInfoResp getInfo(Long id) {
        ScheduleBannerInfo bannerInfo = this.lambdaQuery()
                .eq(ScheduleBannerInfo::getId, id)
                .list()
                .stream()
                .findFirst()
                .orElse(null);
        if (ObjUtil.isEmpty(bannerInfo)){
            throw new RuntimeException("无法找到对象！");
        }
        BannerInfoResp resp = new BannerInfoResp();
        BeanUtil.copyProperties(bannerInfo,resp);
        if (StrUtil.isNotBlank(resp.getBannerImg())){
            List<String> list = dataConversionUtils.strToList(resp.getBannerImg());
            Set<Long> fileIds = CollUtil.newHashSet();
            list.forEach(x->fileIds.add(Long.parseLong(x)));
            Map<Long, FileVo> voMap = fileInfoService.selectFileMapByIds(fileIds);
            List<FileVo> fileList = CollUtil.newArrayList();
            fileIds.forEach(x->{
                if (voMap.containsKey(x)){
                    fileList.add(voMap.get(x));
                }
            });
            if (CollUtil.isNotEmpty(fileList)){
                resp.setBannerUrlVo(fileList);
            }
        }
        return resp;
    }

    @Override
    public void addOrEdit(BannerInfoAddParam param) {
        if (ObjUtil.isEmpty(param.getScheduleId())){
            throw new RuntimeException("赛程数据不能为空！");
        }
        //查询该赛程下已有的轮播数据
        List<ScheduleBannerInfo> infos = this.lambdaQuery()
                .eq(ScheduleBannerInfo::getScheduleId, param.getScheduleId())
                .list();
        //首页
        List<ScheduleBannerInfo> homePageBanner = infos.stream().filter(x -> BannerTypeEnum.HOME_PAGE.equals(x.getBannerType())).collect(Collectors.toList());
        //大赛动态
        List<ScheduleBannerInfo> dynamicBanner = infos.stream().filter(x -> BannerTypeEnum.DYNAMIC.equals(x.getBannerType())).collect(Collectors.toList());
        //我要参赛
        List<ScheduleBannerInfo> takePartBanner = infos.stream().filter(x -> BannerTypeEnum.TAKE_PART.equals(x.getBannerType())).collect(Collectors.toList());
        //往届作品
        List<ScheduleBannerInfo> beforeWorksBanner = infos.stream().filter(x -> BannerTypeEnum.BEFORE_WORKS.equals(x.getBannerType())).collect(Collectors.toList());
        //如果一添加就为启用状态，则判断是否同类型的存在启用中
        if (BannerStatusEnum.ENABLE.equals(param.getBannerStatus())){
            if (CollUtil.isNotEmpty(homePageBanner)&&BannerTypeEnum.HOME_PAGE.equals(param.getBannerType())){
                List<ScheduleBannerInfo> scheduleBannerInfos = homePageBanner.stream().filter(x -> BannerTypeEnum.HOME_PAGE.equals(x.getBannerStatus())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(scheduleBannerInfos)){
                    throw new RuntimeException("存在已经启用的图片数据，请停用后开启！");
                }
            }
            if (CollUtil.isNotEmpty(dynamicBanner)&&BannerTypeEnum.DYNAMIC.equals(param.getBannerType())){
                List<ScheduleBannerInfo> bannerList = dynamicBanner.stream().filter(x -> BannerTypeEnum.DYNAMIC.equals(x.getBannerStatus())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(bannerList)){
                    throw new RuntimeException("存在已经启用的图片数据，请停用后开启！");
                }
            }
            if (CollUtil.isNotEmpty(takePartBanner)&&BannerTypeEnum.TAKE_PART.equals(param.getBannerType())){
                List<ScheduleBannerInfo> bannerList = takePartBanner.stream().filter(x -> BannerTypeEnum.TAKE_PART.equals(x.getBannerStatus())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(bannerList)){
                    throw new RuntimeException("存在已经启用的图片数据，请停用后开启！");
                }
            }
            if (CollUtil.isNotEmpty(beforeWorksBanner)&&BannerTypeEnum.BEFORE_WORKS.equals(param.getBannerType())){
                List<ScheduleBannerInfo> bannerList = beforeWorksBanner.stream().filter(x -> BannerTypeEnum.BEFORE_WORKS.equals(x.getBannerStatus())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(bannerList)){
                    throw new RuntimeException("存在已经启用的图片数据，请停用后开启！");
                }
            }
        }
        ScheduleBannerInfo info = new ScheduleBannerInfo();
        BeanUtil.copyProperties(param,info);
        this.saveOrUpdate(info);
    }

    @Override
    public Boolean deleteOrgInfo(List<Long> ids) {
        if (CollUtil.isEmpty(ids)){
            throw new RuntimeException("没有需要删除的数据！");
        }
        return this.lambdaUpdate()
                .in(ScheduleBannerInfo::getId,ids)
                .remove();
    }

    @Override
    public Boolean editStatus(BannerStatusEditParam param) {
        //如果修改为启用状态，则判断该类型的是否存在已经启用的数据
        if (BannerStatusEnum.ENABLE.equals(param.getBannerStatus())){
            ScheduleBannerInfo bannerInfo = this.getById(param.getId());
            List<ScheduleBannerInfo> bannerInfos = this.lambdaQuery()
                    .eq(ScheduleBannerInfo::getBannerType, bannerInfo.getBannerType())
                    .eq(ScheduleBannerInfo::getBannerStatus, BannerStatusEnum.ENABLE)
                    .list();
            if (CollUtil.isNotEmpty(bannerInfos)){
                throw new RuntimeException("存在已经启用的图片数据，请停用后开启！");
            }
        }
        return this.lambdaUpdate()
                .eq(ScheduleBannerInfo::getId,param.getId())
                .set(ScheduleBannerInfo::getBannerStatus,param.getBannerStatus())
                .update();
    }

    /**
     * 根据类型获取轮播信息
     * @param bannerType
     * @return
     */
    @Override
    public List<BannerResp> getBannerInfoByType(String bannerType,Long scheduleId) {
        BannerInfoAddParam param = new BannerInfoAddParam();
        List<BannerInfoResp> bannerInfoRespList = baseMapper.bannerList(param);
        //过滤类型、启用状态、赛程
        List<BannerInfoResp> filterInfo = bannerInfoRespList.stream().filter(x -> bannerType.equals(x.getBannerType().name())
                && x.getScheduleId().equals(scheduleId)
                && BannerStatusEnum.ENABLE.equals(x.getBannerStatus())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(filterInfo)){
            //组装附件信息
            Set<Long> fileIds = CollUtil.newHashSet();
            Set<String> fileList = filterInfo.stream().map(BannerInfoResp::getBannerImg).collect(Collectors.toSet());
            fileList.forEach(x->{
                List<String> list = dataConversionUtils.strToList(x);
                list.forEach(j->fileIds.add(Long.parseLong(j)));
            });
            if (CollUtil.isNotEmpty(fileIds)){
                Map<Long, FileVo> voMap = fileInfoService.selectFileMapByIds(fileIds);
                filterInfo.forEach(x->{
                    List<FileVo> fileVos = new ArrayList<>();
                    List<String> toList = dataConversionUtils.strToList(x.getBannerImg());
                    toList.forEach(j->fileVos.add(voMap.get(Long.parseLong(j))));
                    x.setBannerUrlVo(fileVos);
                });
            }
            BannerInfoResp bannerInfoResp = filterInfo.get(0);
            if (CollUtil.isNotEmpty(bannerInfoResp.getBannerUrlVo())){
                List<BannerResp> bannerResps = bannerInfoResp.getBannerUrlVo().stream().map(x -> {
                    BannerResp resp = new BannerResp();
                    resp.setFileUrl(x.getFileUrl());
                    return resp;
                }).collect(Collectors.toList());
                return bannerResps;
            }
        }
        return CollUtil.newArrayList();
    }


}
